home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / utilitys / cpublit1 / part01 / src / small.a < prev    next >
Text File  |  1991-05-08  |  7KB  |  262 lines

  1. *:ts=8
  2. ******************************************************************************
  3. *                                         *
  4. *    SMALL.A                  (C) Copyright Eddy Carroll 1991    *
  5. *    ~~~~~~~                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    *
  6. *                                         *
  7. *    Replacement startup code for Lattice C V5.10a. Use instead of c.o.   *
  8. *    This has many features stripped out to allow small utilities to      *
  9. *    have as small a filesize as possible. If you use this, don't call    *
  10. *    any stdio functions.                             *
  11. *                                                                            *
  12. *     In some of my earlier projects, I used a similar file called tiny.a. *
  13. *    Small.a is essentially that file but with Workbench support added.   *
  14. *    avoid confusion between the two.                     *
  15. *                                                                            *
  16. ******************************************************************************
  17.  
  18.     INCLUDE "exec/types.i"
  19.     INCLUDE "exec/execbase.i"
  20.     INCLUDE "exec/nodes.i"
  21.     INCLUDE "exec/lists.i"
  22.     INCLUDE "exec/ports.i"
  23.     INCLUDE "exec/libraries.i"
  24.     INCLUDE "exec/tasks.i"
  25.     INCLUDE "libraries/dos.i"
  26.     INCLUDE "libraries/dosextens.i"
  27.     INCLUDE "workbench/startup.i"
  28.     INCLUDE "exec/funcdef.i"
  29.     INCLUDE "exec/exec_lib.i"
  30.     INCLUDE "libraries/dos_lib.i"
  31.  
  32. MAXARGS        EQU 100    ; Maximum number of command line arguments from CLI
  33. AbsExecBase EQU 4    ; Welcome to the only fixed point in the universe
  34.  
  35. * A useful macro to let us call library routines
  36. callsys macro
  37.     CALLLIB _LVO\1
  38.     endm
  39.  
  40.     xdef    XCEXIT
  41.     xdef    exit
  42.     xref    LinkerDB
  43.     xref    _BSSBAS
  44.     xref    _BSSLEN
  45.  
  46.     csect    text,0,0,1,2        * xref's after this are 16-bit reloc
  47.     xref    main            * Name of C program to start with.
  48.  
  49. start:
  50.     movem.l d1-d6/a0-a6,-(a7)
  51. REGSIZE EQU    (6+7)*4
  52.     lea    REGSIZE(a7),A5        * Determine old stack pointer
  53.     move.l    a0,a2            * Save command pointer
  54.     move.l    d0,d2            * and command length
  55.     lea    LinkerDB,a4        * Load base register
  56.  
  57.     move.l    AbsExecBase.W,a6
  58.     move.l    a6,SysBase(A4)
  59.     move.l    a7,_StackPtr(A4)    * Save stack ptr
  60.  
  61.     move.l    a5,D0              * get top of stack
  62.     sub.l    4(a5),D0        * compute bottom
  63.     add.l    #128,D0         * allow for parms overflow
  64.     move.l    D0,_base(A4)        * save for stack checking
  65.  
  66.     lea    DOSName(A4),A1
  67.     moveq.l    #0,D0
  68.     callsys    OpenLibrary
  69.     move.l    D0,DOSBase(A4)
  70.     beq    NoDos
  71.  
  72.     move.l    ThisTask(a6),a3        * Get our task ID
  73.     tst.l    pr_CLI(a3)        * Running from Workbench?
  74.     bne.s    getcom            * If no, skip to do CLI stuff
  75.     lea    pr_MsgPort(a3),a0    * Our process port
  76.     callsys    WaitPort        * Wait for Workbench startup message
  77.     lea    pr_MsgPort(a3),a0    * Get our message port again
  78.     callsys    GetMsg            * Get startup message
  79.     move.l    d0,WBenchMsg(a4)    * Save pointer to it
  80.     move.l    d0,-(sp)        * Save it as argv
  81.     moveq    #0,d0            * And push argc of 0 to indicate WB
  82.     move.l    d0,-(sp)        *
  83.     bra    cont            * Skip to init BSS and start prog
  84.  
  85. *------ find command name:
  86. getcom:
  87.     move.l  pr_CLI(a3),a0
  88.     add.l    a0,a0
  89.     add.l    a0,a0
  90.     move.l    cli_CommandName(a0),a1
  91.     add.l    a1,a1
  92.     add.l    a1,a1
  93.  
  94. *------ collect parameters:
  95.     move.l    d2,d0            * get command line length
  96.     moveq.l #0,d1
  97.     move.b    (a1)+,d1
  98.     move.l    a1,_ProgramName(A4)
  99.     add.l    d1,d0            * add length of command name
  100.     addq.l    #1,d0            * allow for space after command
  101.  
  102.     clr.w    -(A7)            * set null terminator for command line
  103.     addq.l    #1,D0            * force to even number of bytes
  104.     andi.w    #$fffe,D0        * (round up)
  105.     sub.l    D0,A7            * make room on stack for command line
  106.     subq.l    #2,D0
  107.     clr.w    0(A7,D0)
  108.  
  109. *------ copy command line onto stack
  110.     move.l    d2,d0            * get command line length
  111.     subq.l    #1,d0
  112.     add.l    d1,d2
  113.  
  114. copy_line:
  115.     move.b    0(A2,D0.W),0(A7,D2.W)    * copy command line to stack
  116.     subq.l    #1,d2
  117.     dbf    d0,copy_line
  118.     move.l    d2,d0            * save offset to argv[1] - 1
  119.     clr.b    0(a7,d2.w)         * Insert command name terminator
  120.     subq.l    #1,d2
  121.  
  122. copy_cmd:
  123.     move.b    0(a1,d2.w),0(a7,d2.w)    * copy command name to stack
  124.     dbf    d2,copy_cmd
  125.     lea    1(a7,d0.w),a1        * get pointer to start of arguments
  126.     move.l    a7,a2            * get pointer for argv[0]
  127.  
  128.     sub.l    #(MAXARGS*4),a7        * Reserve space for argv[]
  129.     move.l    a7,a3            * Save ptr to base of argv (&argv[0])
  130.     move.l    a2,(a7)            * Setup argv[0] to point to cmd line
  131.     lea    4(a7),a2        * Init base into array at argv[1]
  132.     moveq    #1,d2            * Initialise argc
  133.  
  134. *
  135. * From here on down, A1 is pointer into command line
  136. *
  137. build_argv:
  138.     bsr.s    getnext            * Read next character from line
  139.     bcs.s    doquote            * If quote, handle
  140.     beq.s    build_argv        * If white space, skip over it
  141.  
  142.     lea    -1(a1),a0        * Get address of this parameter
  143.     bsr.s    bumpargv        * Store it to argv[] array
  144. build_2:
  145.     bsr.s    getnext            * Get next character
  146.     bne.s    build_2            * If not white space, keep looking
  147.     clr.b    -1(a1)            * Zero-terminate current argument
  148.     bra.s    build_argv        * And go back to get next argument
  149.  
  150. doquote:
  151.     move.l    a1,a0            * Get pointer to this argument
  152.     bsr.s    bumpargv        * Output it to argv[]
  153. quote_2:
  154.     bsr.s    getnext            * Get next character
  155.     bcc.s    quote_2            * If not quote, keep looking
  156.     clr.b    -1(a1)            * Zero-terminate current argument
  157. quote_3:
  158.     bsr.s    getnext            * Get next character
  159.     bne.s    quote_3            * Skip until space reached
  160.     beq.s    build_argv        * Go back and read next argument
  161.  
  162. bumpargv:
  163.     move.l    a0,(a2)+        * Output ptr to current argument
  164.     addq    #1,d2            * Increment argc
  165.     cmpi    #MAXARGS,d2        * Used up all our arguments yet?
  166.     bls.s    qrts            * If not, then return
  167.     moveq    #110,d0            * Else set return code
  168.     bra.s    exit2            * And exit
  169.  
  170. *
  171. * Reads next character from command line. If zero, never returns, but
  172. * drops into call to main. Else, returns, with C=1 if character is quote,
  173. * Z=1 if character is white space.
  174. *
  175. getnext:
  176.     move.b    (a1)+,d0        * Get character from command line
  177.     beq.s    get_2            * Exit if end of line
  178.     cmp.b    #34,d0            * Check if quote
  179.     beq.s    isquote            *
  180.     cmp.b    #32,d0            * Check if space
  181.     beq.s    isspace            *
  182.     cmp.b    #9,d0            * Or tab
  183.     beq.s    isspace            *
  184.     cmp.b    #10,d0            * Or end of line
  185. isspace:
  186.     andi    #$1E,ccr        * Clear carry flag, retaining Z
  187. qrts    rts
  188.  
  189. isquote:
  190.     ori    #1,ccr            * Set carry flag
  191.     andi    #$FB,ccr        * Clear zero flag
  192.     rts                * And return
  193.  
  194. get_2:
  195.     move.l    a3,-(a7)        * Push argv onto stack
  196.     move.l    d2,-(a7)        * Push argc onto stack
  197.  
  198. cont:
  199.     lea    _BSSBAS,a3        * get base of BSS
  200.     moveq    #0,d1
  201.     move.l    #_BSSLEN,d0        * get length of BSS in longwords
  202.     bra.s    clr_lp            * and clear for length given
  203. clr_bss move.l    d1,(a3)+
  204. clr_lp    dbf    d0,clr_bss
  205.  
  206. domain:
  207.     jsr    main(PC)        * Call main(argc,argv)
  208.     moveq.l #0,d0            * Set successful status
  209.     bra.s    exit2
  210.  
  211. NoDos:
  212.     moveq.l    #100,d0            * Exit thread if no dos.library
  213.     bra.s    exit2            *
  214.  
  215. exit:
  216. _exit:
  217. XCEXIT:
  218.     move.l    4(SP),d0        * Extract return code
  219. exit2:
  220.     move.l    d0,-(a7)
  221.     move.l    AbsExecBase.W,a6
  222.     move.l    DOSBase(A4),a1
  223.     callsys CloseLibrary        * Close Dos library
  224.  
  225. *------ this rts sends us back to DOS:
  226.     tst.l    WBenchMsg(a4)        * Did we run from Workbench
  227.     beq.s    ExitToDOS        * If not, skip WB cleanup
  228.     move.l    SysBase(A4),a6        *
  229.     callsys    Forbid            * Stop Workbench unloading us too soon
  230.     move.l    WBenchMsg(a4),a1    *
  231.     callsys    ReplyMsg        * Return our startup msg
  232.  
  233. ExitToDOS:
  234.     move.l    (A7)+,D0
  235.     movea.l _StackPtr(a4),SP    * Restore stack ptr
  236.     movem.l (a7)+,d1-d6/a0-a6
  237.     rts
  238.  
  239. *-----------------------------------------------------------------------
  240. * Global definitions
  241. *
  242.     csect    __MERGED,1,,2,2
  243.  
  244.     xdef    NULL,SysBase,LoadAddress,DOSBase
  245.     xdef    _oserr,_OSERR,_ONBREAK
  246.     xdef    _ProgramName,_StackPtr,_base,WBenchMsg
  247.  
  248. NULL           dc.l    0
  249. _base           dc.l    0
  250. _oserr           equ     *
  251. _OSERR           dc.l    0
  252. _ONBREAK       dc.l    0
  253. SysBase        dc.l    0
  254. LoadAddress    dc.l    0
  255. _StackPtr      dc.l    0
  256. DOSBase        dc.l    0
  257. _ProgramName   dc.l    0
  258. WBenchMsg      dc.l    0
  259. DOSName        dc.b    'dos.library',0
  260.  
  261.     END
  262.